#include "Texture.h"
#include "../framework/FileSystem.h"
#include "PVRTTexture.h"
#include "PVRTTextureAPI.h"
#include "PVRTglesExt.h"

Texture::Texture()
:
    imgName(),
    fullPath(),
    type(TT_2D),
    layer(TL_DIFFUSE),
    filter(TF_LINEAR),
    repeat(TR_CLAMP),
    width(0),
    height(0),
    depth(0),
    mipLevel(0),
    texId(0)
{

}

Texture::~Texture() {
    glDeleteTextures(1, &texId);
}

static const GLenum GL_TEXTURE_TYPE_MAP[] = {
    GL_TEXTURE_2D
};

void Texture::Bind() {
    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_TYPE_MAP[type], texId );
}

void Texture::Unbind() {
    glBindTexture( GL_TEXTURE_TYPE_MAP[type], 0 );
}

TextureManager textureManagerLocal;
TextureManager* textureManager = &textureManagerLocal;

static inf::Str textureRoot;


TextureManager::TextureManager()
{

}

TextureManager::~TextureManager()
{

}

void TextureManager::Init()
{
    inf::Str    baseDir = fileSystem->GetMediaPath();
    baseDir += "/texture/";

    textureRoot = baseDir;

    defaultTexture = CreateFromFile("defaultTexture.pvr");
    errorTexture = CreateFromFile("errorTexture.pvr");
}

void TextureManager::Shutdown()
{
    textureRoot.empty();

    inf::delete_contents( textures, false );
    textures.clear();

    defaultTexture = errorTexture = NULL;
}

Texture* TextureManager::CreateFromFile( const char* fileName )
{
    Texture*    pNew = NULL;
    inf::Str    str( fileName );

    str.extract_file_name( str );
    inf::Str    imgName = str;

    str = textureRoot;
    str += fileName;
    inf::Str    fullPath = str;

    pNew = CheckExist( fullPath );
    if( pNew ) {
        return pNew;
    }

    pNew = new Texture;
    pNew->imgName = imgName;
    pNew->fullPath = fullPath;

    PVRTextureHeaderV3 texHeader;
    if( !PVRTTextureLoadFromPVR( pNew->fullPath, &pNew->texId, &texHeader ) ) {
        delete pNew;
        common->Error( "Failed to load texture: %s\n", fullPath.c_str() );
        return NULL;
    }

    textures.append( pNew );
    return pNew;
}

Texture* TextureManager::CheckExist( const char* fileName )
{
    TextureList::iterator it = textures.begin();
    for( ; it != textures.end(); ++it ) {
        if( *it && ((*it)->fullPath.cmp(fileName)==0) ) {
            return *it;
        }
    }

    common->Warning( "Not exist texture from: %s\n", fileName );
    return NULL;
}
